package ynu.edu.model.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.injector.methods.SelectOne;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import ynu.edu.common.domain.R;
import ynu.edu.common.exception.BadRequestException;
import ynu.edu.common.exception.BizIllegalException;
import ynu.edu.common.utils.UserContext;
import ynu.edu.model.domain.GeneratedImage;
import ynu.edu.model.mapper.ImagePredictMapper;
import ynu.edu.model.service.ImagePredictService;
import ynu.edu.model.utils.AliOssUtil;
import ynu.edu.model.utils.HttpClientUtil;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
@RequiredArgsConstructor
@Slf4j
public class ImagePredictServiceImpl extends ServiceImpl<ImagePredictMapper, GeneratedImage> implements ImagePredictService {

    private final AliOssUtil aliOssUtil;

    private final ImagePredictMapper imagePredictMapper;

    /**
     * 生成图片并保存到数据库
     * @param params
     * @return
     */
    @Override
    public GeneratedImage saveImage(Map<String, Object> params) {
        try {
            // 获取前端传递的参数并进行正确的类型转换
            int seed = Integer.parseInt(String.valueOf(params.get("seed")));
            double truncationPsi = Double.parseDouble(String.valueOf(params.get("truncationPsi")));

            // 在这里调用 Python 后端进行图片生成并返回结果
            String pythonBackendUrl = "http://localhost:5000/predict";  // Python后端URL
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("seed", seed);
            paramMap.put("truncationPsi", truncationPsi);

            // 调用Python后端接口
            String response = HttpClientUtil.doPost(pythonBackendUrl, JSONObject.toJSONString(paramMap));
            log.info("Python后端返回结果长度: {}", response != null ? response.length() : 0);

            // 解析返回的JSON
            JSONObject jsonResponse = JSONObject.parseObject(response);
            if (jsonResponse.containsKey("error")) {
                String errorMsg = jsonResponse.getString("error");
                log.error("Python后端返回错误：{}", errorMsg);
                return null;
            }

            String predictedImageBase64 = jsonResponse.getString("predictedImage");
            if (predictedImageBase64 == null || predictedImageBase64.isEmpty()) {
                log.error("Python后端返回的图片数据为空");
                return null;
            }

            // 生成OSS路径
            String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
            String fileName = String.format("generated_images/%s/seed_%d_psi_%.2f_%s.png",
                    dateStr, seed, truncationPsi,
                    System.currentTimeMillis());

            // 将Base64编码的字符串解码为字节数组
            byte[] imageBytes = Base64.getDecoder().decode(predictedImageBase64);

            // 将预测后的图片上传到OSS
            String ossUrl = aliOssUtil.upload(imageBytes, fileName);
            log.info("图片上传OSS成功，URL: {}", ossUrl);

            Long userId = UserContext.getUser();

            // 保存到数据库
            GeneratedImage generatedImage = new GeneratedImage();
            generatedImage.setSeed(seed);
            generatedImage.setTruncationPsi(truncationPsi);
            generatedImage.setImageUrl(ossUrl);
            generatedImage.setOssPath(fileName);
            generatedImage.setCreateTime(LocalDateTime.now());
            generatedImage.setUpdateTime(LocalDateTime.now());

            if (userId != null){
                generatedImage.setUserId(userId);
            }

            save(generatedImage);
            log.info("图片信息已保存到数据库，ID: {}", generatedImage.getId());

            // 返回预测后的图片的OSS URL
            return generatedImage;
        } catch (IOException e) {
            log.error("图片预测失败", e);
            return null;
        } catch (Exception e) {
            log.error("处理请求时发生未知错误", e);
            return null;
        }
    }

    /**
     * 查询用户最新生成的图片
     * @param limit
     * @return
     */
    @Override
    public List<GeneratedImage> findRecent(int limit) {
        try {
            List<GeneratedImage> history = list(new LambdaQueryWrapper<GeneratedImage>()
                    .orderByDesc(GeneratedImage::getCreateTime)
                    .last("limit " + limit));
            log.info("查询到 {} 条历史记录", history.size());
            return history;
        } catch (Exception e) {
            log.error("获取历史记录失败", e);
            return null;
        }
    }

    /**
     * 查询用户最新生成的图片
     * 返回用户最新生成的图片的URL
     * @param userId
     * @return
     */
    @Override
    public GeneratedImage getUserImage(long userId) {
        log.info("查询用户{}最新生成的图片", userId);
        QueryWrapper<GeneratedImage> queryWrapper = new QueryWrapper<GeneratedImage>()
                .eq("user_id", userId)
                .orderByDesc("create_time")
                .last("limit 1");
        GeneratedImage generatedImage = imagePredictMapper.selectOne(queryWrapper);
        if (generatedImage != null) {
            log.info("查询到用户{}最新生成的图片，URL: {}", userId, generatedImage.getImageUrl());
            return generatedImage;
        } else {
            log.info("用户{}没有生成过图片", userId);
            return null;
        }
    }

    /**
     * 上传头像
     * @param file
     * @return
     */
    @Override
    public GeneratedImage uploadAvatar(MultipartFile file) {
        if (file.isEmpty()) {
            log.error("上传文件为空");
            throw new BadRequestException("上传文件为空");
        }

        // 验证文件类型
        String contentType = file.getContentType();
        if (contentType == null || (!contentType.equals("image/jpeg") && !contentType.equals("image/png"))) {
            throw new BadRequestException("上传文件类型错误");
        }

        // 验证文件大小
        if (file.getSize() > 2 * 1024 * 1024) {
            throw new BadRequestException("上传文件大小超过2MB");
        }

        try {
            // 生成OSS路径
            String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
            String fileName = String.format("avatars/%s/%s%s",
                    dateStr,
                    UUID.randomUUID().toString(),
                    getFileExtension(file.getOriginalFilename()));

            // 上传到OSS
            String ossUrl = aliOssUtil.upload(file.getBytes(), fileName);
            log.info("头像上传OSS成功，URL: {}", ossUrl);

            // 获取当前用户ID
            Long userId = UserContext.getUser();
            log.info("用户ID: {}", userId);
            if (userId == null) {
                throw new BizIllegalException("用户未登录或会话已过期");
            }

            // 保存到数据库
            GeneratedImage generatedImage = new GeneratedImage();
            generatedImage.setUserId(userId);
            generatedImage.setImageUrl(ossUrl);
            generatedImage.setOssPath(fileName);
            generatedImage.setCreateTime(LocalDateTime.now());
            generatedImage.setUpdateTime(LocalDateTime.now());

            save(generatedImage);
            log.info("头像信息已保存到数据库，ID: {}", generatedImage.getId());

            return generatedImage;
        } catch (Exception e) {
            log.error("上传头像失败", e);
            throw new BizIllegalException("上传头像失败");
        }
    }

    @Override
    public GeneratedImage generate(Map<String, Object> params) {
        return null;
    }

    private String getFileExtension(String filename) {
        if (filename == null) return ".jpg";
        int lastDotIndex = filename.lastIndexOf(".");
        return lastDotIndex == -1 ? ".jpg" : filename.substring(lastDotIndex);
    }

}
